import { NextRequest, NextResponse } from 'next/server';
import { logger } from '../logger';

// 日志记录中间件
export function withLogging(handler: Function) {
  return async (request: NextRequest) => {
    const startTime = Date.now();
    const method = request.method;
    const url = request.url;
    const userAgent = request.headers.get('user-agent') || 'Unknown';
    const ip = request.headers.get('x-forwarded-for') || 
               request.headers.get('x-real-ip') || 
               'Unknown';

    try {
      // 记录请求开始
      logger.info(`Request started: ${method} ${url}`, {
        method,
        url,
        userAgent,
        ip,
        timestamp: new Date().toISOString()
      });

      // 执行原始处理器
      const response = await handler(request);
      
      // 计算响应时间
      const responseTime = Date.now() - startTime;
      const statusCode = response?.status || 200;

      // 记录成功响应
      logger.http(method, url, statusCode, responseTime, userAgent);
      
      // 记录请求完成
      logger.info(`Request completed: ${method} ${url}`, {
        method,
        url,
        statusCode,
        responseTime,
        userAgent,
        ip,
        timestamp: new Date().toISOString()
      });

      return response;

    } catch (error) {
      // 计算响应时间
      const responseTime = Date.now() - startTime;
      
      // 记录错误
      logger.error(`Request failed: ${method} ${url}`, {
        method,
        url,
        error: error instanceof Error ? error.message : String(error),
        stack: error instanceof Error ? error.stack : undefined,
        responseTime,
        userAgent,
        ip,
        timestamp: new Date().toISOString()
      });

      // 重新抛出错误，让错误处理中间件处理
      throw error;
    }
  };
}

// 数据库操作日志装饰器
export function withDbLogging<T extends any[], R>(
  operation: string,
  table: string,
  handler: (...args: T) => Promise<R>
) {
  return async (...args: T): Promise<R> => {
    const startTime = Date.now();
    
    try {
      const result = await handler(...args);
      const duration = Date.now() - startTime;
      
      logger.db(operation, table, duration, true);
      return result;
      
    } catch (error) {
      const duration = Date.now() - startTime;
      
      logger.db(operation, table, duration, false, {
        error: error instanceof Error ? error.message : String(error),
        stack: error instanceof Error ? error.stack : undefined
      });
      
      throw error;
    }
  };
}

// API操作日志装饰器
export function withApiLogging<T extends any[], R>(
  apiName: string,
  method: string,
  handler: (...args: T) => Promise<R>
) {
  return async (...args: T): Promise<R> => {
    const startTime = Date.now();
    
    try {
      const result = await handler(...args);
      const duration = Date.now() - startTime;
      
      logger.api(apiName, method, duration, true);
      return result;
      
    } catch (error) {
      const duration = Date.now() - startTime;
      
      logger.api(apiName, method, duration, false, {
        error: error instanceof Error ? error.message : String(error),
        stack: error instanceof Error ? error.stack : undefined
      });
      
      throw error;
    }
  };
}

// 用户操作日志装饰器
export function withUserActionLogging<T extends any[], R>(
  userId: string,
  action: string,
  handler: (...args: T) => Promise<R>
) {
  return async (...args: T): Promise<R> => {
    try {
      const result = await handler(...args);
      
      logger.userAction(userId, action, {
        success: true,
        timestamp: new Date().toISOString()
      });
      
      return result;
      
    } catch (error) {
      logger.userAction(userId, action, {
        success: false,
        error: error instanceof Error ? error.message : String(error),
        timestamp: new Date().toISOString()
      });
      
      throw error;
    }
  };
}
